package us.mooresr.aircraftscheduling.client.ui;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

import us.mooresr.aircraftscheduling.shared.model.Reservation;
import us.mooresr.aircraftscheduling.shared.model.User;

import com.gwtplatform.mvp.client.PopupViewImpl;
import com.gwtplatform.mvp.client.PopupViewWithUiHandlers;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DateBox.DefaultFormat;
import com.google.gwt.user.datepicker.client.DateBox.Format;
import com.google.gwt.user.datepicker.client.DatePicker;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.inject.Inject;
import com.summatech.gwt.client.HourMinutePicker;

public class ReservationDetailView extends PopupViewWithUiHandlers<ReservationDetailUiHandlers> implements
		ReservationDetailPresenter.MyView {

	private final PopupPanel widget;
	private Long currentReservationId;
	private HashMap<String,Long> userIdMap;
	private HashMap<Long, Integer> userIndexMap;
	private Boolean isAdmin = false;
	private Long currentUserId;
	
	@UiField
	ListBox reservedBy;
	
	@UiField(provided=true)
	DateBox startDate;
	
	@UiField
	TimePicker startTime;
	
	@UiField(provided=true)
	DateBox endDate;
	
	@UiField
	TimePicker endTime;
	
	@UiField
	TextArea notes;

	public interface Binder extends UiBinder<PopupPanel, ReservationDetailView> {
	}

	@Inject
	public ReservationDetailView(final EventBus eventBus, final Binder binder) {
		super(eventBus);
		
		startDate = new DateBox();
		endDate = new DateBox();
		
		currentReservationId = null;
		userIdMap = new HashMap<String,Long>();
		userIndexMap = new HashMap<Long, Integer>();
		
		DefaultFormat format = new DefaultFormat(DateTimeFormat.getFormat("EEE, MMM d, y"));
		startDate.setFormat(format);
		endDate.setFormat(format);
		
		widget = binder.createAndBindUi(this);
		widget.setGlassEnabled(true);
		
		

	}

	@Override
	public Widget asWidget() {
		return widget;
	}
	
	@UiHandler("startDate")
	void startDateValueChanged(ValueChangeEvent<Date> event) {
		// When the start date changes, if the end date is earlier than
		// the start date then set the end date to be equal to the start date
		Date endValue = endDate.getValue();
		Date startValue = startDate.getValue();
		
		if (endDate.getValue().before(startDate.getValue())) {
			endDate.setValue(startDate.getValue());
		}
		
	}
	
	@UiHandler("cancelButton")
	void cancelButtonClicked(ClickEvent event) {
		widget.hide();
	}
	
	@SuppressWarnings("deprecation")
	@UiHandler("okButton")
	void okButtonClicked(ClickEvent event) {
		// Validate the data
		// TODO:  Add validation code here
		
		Date start = startDate.getValue();
		Date end = endDate.getValue();
		
		int startHour = startTime.getHour();
		int startMinute = startTime.getMinute();
		start.setHours(startHour);
		start.setMinutes(startMinute);

		int endHour = endTime.getHour();
		int endMinute = endTime.getMinute();
		end.setHours(endHour);
		end.setMinutes(endMinute);
		
		if (end.before(start)) {
			Window.alert("End date is before start date");
			return;
		}
		
		Date today = new Date();
		today.setHours(0);
		today.setMinutes(0);
		if (start.before(today)) {
			if (Window.confirm("Reservation starts in the past.  Are you sure?") == false) {
				return;
			}
		}
		
		Long userId = userIdMap.get(reservedBy.getValue(reservedBy.getSelectedIndex()));
		Reservation newReservation = new Reservation(currentReservationId, userId, null, 
				notes.getValue(), start, end);
		newReservation.setReservingUserName(reservedBy.getValue(reservedBy.getSelectedIndex()));
		
		
		if (currentReservationId == null) {
			// Call the presenter's CreateReservation handler to create the reservation
			getUiHandlers().createReservation(newReservation);
		} else {
			// Call the presenter's EditReservation handler to update the reservation
			getUiHandlers().updateReservation(newReservation);
		}
		
		// Dismiss the dialog
		widget.hide();
	}

	@Override
	public void clear() {
		reservedBy.setSelectedIndex(0);
		startDate.setValue(new Date());
		startTime.clear();
		endDate.setValue(new Date());
		endTime.clear();
		notes.setText("");
		
		currentReservationId = null;
		
		
	}

	@Override
	public void loadUserPopup(List<User> users) {
		reservedBy.clear();
		userIdMap.clear();
		userIndexMap.clear();
		Integer index = 0;
		
		for (User u : users) {
			if (isAdmin == false) {
				if (!u.getUserId().equals(currentUserId)) {
					continue;
				}
			}
			reservedBy.addItem(u.getName());
			userIdMap.put(u.getName(), u.getUserId());
			userIndexMap.put(u.getUserId(), index);
			++index;
		}
		

		
	}

	@Override
	public void setData(Reservation reservation) {
		reservedBy.setSelectedIndex(userIndexMap.get(reservation.getReservingUserId()));
		startDate.setValue(reservation.getStart());
		startTime.setHour(reservation.getStart().getHours());
		startTime.setMinute(reservation.getStart().getMinutes());
		endDate.setValue(reservation.getEnd());
		endTime.setHour(reservation.getEnd().getHours());
		endTime.setMinute(reservation.getEnd().getMinutes());
		notes.setText(reservation.getNotes());
		currentReservationId = reservation.getReservationId();
		
	}

	@Override
	public void setUserData(Boolean isAdmin, Long currentUserId) {
		this.isAdmin = isAdmin;
		this.currentUserId = currentUserId;
		
	}
}
